#include "CEUtilities.h"

#include "CEMouse.h"


Mouse* Mouse::c_Mouse = NULL;


//----------------------------------------------------------------------
Mouse::Mouse()
{
}


//----------------------------------------------------------------------
Mouse::~Mouse()
{
}


//----------------------------------------------------------------------
Mouse* Mouse::GetSingleton()
{
	if (!c_Mouse)
	{
		c_Mouse = new Mouse();
	}

	return c_Mouse;
}


//----------------------------------------------------------------------
BOOL Mouse::OnCreateMouse(HWND hwnd, int left, int top, int right, int bottom)
{
	m_Pos.x = (left + right) / 2;
	m_Pos.y = (top + bottom) / 2;
	m_Scope.left = left;
	m_Scope.right = right;
	m_Scope.top = top;
	m_Scope.bottom = bottom;
	m_dOldClickedTime = -1;

	return OnCreateDevice(hwnd, GUID_SysMouse, &c_dfDIMouse2, 1);
}


//----------------------------------------------------------------------
BOOL Mouse::IsMouseKeyDown(int type, BOOL lastSensitive)
{
	return IsKeyDown(m_State.rgbButtons,m_OldState.rgbButtons,type,lastSensitive);
}


//----------------------------------------------------------------------
BOOL Mouse::IsMouseKeyUp(int type, BOOL lastSensitive)
{
	return IsKeyUp(m_State.rgbButtons,m_OldState.rgbButtons,type,lastSensitive);
}


//----------------------------------------------------------------------
BOOL Mouse::IsMouseDoubleClicked(REAL duringTime)
{
	DWORD currentTime = timeGetTime();

	if (IsMouseKeyDown(0, TRUE))
	{
		DWORD timePassed = currentTime - m_dOldClickedTime;
		if (timePassed <= (DWORD)(duringTime * 1000) && (m_dOldClickedTime != -1))
		{
			m_dOldClickedTime = -1;
			return TRUE;
		}
		m_dOldClickedTime = currentTime;
	}

	return FALSE;
}


//----------------------------------------------------------------------
int Mouse::GetScroll()
{
	return m_State.lZ;
}


//----------------------------------------------------------------------
int Mouse::GetX()
{
	return m_ClientPos.x;
}


//----------------------------------------------------------------------
int Mouse::GetY()
{
	return m_ClientPos.y;
}


//----------------------------------------------------------------------
Point2D<int> Mouse::GetPos()
{
	return m_ClientPos;
}


//----------------------------------------------------------------------
void Mouse::SetPos(int x, int y)
{
	m_Pos.x = x;
	m_Pos.y = y;
}


//----------------------------------------------------------------------
void Mouse::SetPos(Point2D<int> newMouse)
{
	m_Pos.x = newMouse.x;
	m_Pos.y = newMouse.y;
}


//----------------------------------------------------------------------
Scope Mouse::GetScope()
{
	return m_Scope;
}


//----------------------------------------------------------------------
void Mouse::SetScope(int left, int top, int right, int bottom)
{
	m_Scope.left = left;
	m_Scope.top = top;
	m_Scope.right = right;
	m_Scope.bottom = bottom;
}


//----------------------------------------------------------------------
void Mouse::SetScope(Point2D<int> LeftTop, Point2D<int> RightBottom)
{
	m_Scope.left = LeftTop.x;
	m_Scope.top = LeftTop.y;
	m_Scope.right = RightBottom.x;
	m_Scope.bottom =RightBottom.y;
}


//----------------------------------------------------------------------
BOOL Mouse::Update(HWND hwnd)
{
	HRESULT	hr;

	if (_SaveState2Old(m_State.rgbButtons,m_OldState.rgbButtons,MouseBuffer))
	{
		hr = m_pDevice->GetDeviceState(sizeof(DIMOUSESTATE2), &m_State);
	}
	else
	{
		return FALSE;
	}

    if (_CheckState(hr))
	{
		if (0 != m_State.lY)
		{
			m_Pos.y += m_State.lY;
			if (m_Scope.bottom<m_Pos.y)
			{
				m_Pos.y = m_Scope.bottom;
			}
			if (m_Scope.top>m_Pos.y)
			{
				m_Pos.y = m_Scope.top;
			}
		}

		if (0 != m_State.lX)
		{
			m_Pos.x += m_State.lX;
			if (m_Scope.left>m_Pos.x)
			{
				m_Pos.x = m_Scope.left;
			}
			if (m_Scope.right<m_Pos.x)
			{
				m_Pos.x = m_Scope.right;
			}
		}
	}
	else
	{
		return FALSE;
	}
	
	::SetCursorPos(m_Pos.x,m_Pos.y);

	static POINT p;
	p.x = m_Pos.x;
	p.y = m_Pos.y;
	ScreenToClient(hwnd, &p);
	m_ClientPos.x = p.x;
	m_ClientPos.y = p.y;

	return TRUE;
}